package jm_base

import (
	"context"
	"database/sql"
	"git.mycaigou.com/gfyx/common/tenant_db"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/org"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	"git.myscrm.cn/golang/stark/v4"
	"gorm.io/gorm"
	"time"
)

type JmBaseRepository struct {
	tenant_db.TenantDB
}

// NewJmBaseRepository 构造函数
func NewJmBaseRepository() *JmBaseRepository {
	return &JmBaseRepository{}
}

// BuildTrees 构建多棵树
func (r *JmBaseRepository) buildTrees(nodes []*MyBusinessUnitItem) []*MyBusinessUnitItem {
	nodeMap := make(map[string]*MyBusinessUnitItem)

	// 创建节点映射
	for _, nd := range nodes {
		nodeMap[nd.BUGUID] = nd
	}

	// 构建树结构
	var trees []*MyBusinessUnitItem
	for _, nd := range nodes {
		if nd.ParentGUID == "" {
			trees = append(trees, nd)
		} else {
			parent, ok := nodeMap[nd.ParentGUID]
			if ok {
				parent.Children = append(parent.Children, nd)
			}
		}
	}

	return trees
}

// CheckJmAndNewData 数据验证
func (r *JmBaseRepository) CheckJmAndNewData(ctx context.Context) error {
	return nil
}

// WriteOrgToJm 组织架构数据变更到建模, operateType, 1: 新增；2：更新；3：删除
func (r *JmBaseRepository) WriteOrgToJm(ctx context.Context, operateType int32, orgObj *org.GfyOrganizationPo) (int64, error) {
	return 0, nil
}

// WriteUserToJm 用户数据变更到建模，operateType, 1: 新增；2：更新；3：删除
func (r *JmBaseRepository) WriteUserToJm(ctx context.Context, operateType int32, orgObj *user.GfyxUserPo) (int64, error) {
	return 0, nil
}

// SyncFromJmToNewBase 同步数据jm base data to new base data
func (r *JmBaseRepository) SyncFromJmToNewBase(ctx context.Context) error {
	db := r.GetTenantDB(ctx)
	// 1. 同步组织数据
	err := r.saveOrg(ctx, db)
	if err != nil {
		stark.Logger.Errorf(ctx, "SyncFromJmToNewBase-saveOrg-err: %+v", err)
		return err
	}

	// 2. 同步用户
	err = r.saveUserAndUserOrgRel(ctx, db)
	if err != nil {
		stark.Logger.Errorf(ctx, "SyncFromJmToNewBase-saveUserAndUserOrgRel-err: %+v", err)
		return err
	}

	return nil
}

func (r *JmBaseRepository) saveUserAndUserOrgRel(ctx context.Context, db *gorm.DB) error {
	myUserList := make([]*MyUser, 0)
	err := db.Find(&myUserList).Error
	if err != nil {
		return err
	}

	for _, userItem := range myUserList {
		var status int32
		status = 1
		if userItem.IsDisabeld == 1 {
			status = 2
		}

		// 1. 检查账号是否存在
		var userPo user.GfyxUserPo
		err = db.Table(user.GfyxUserPo{}.TableName()).
			Where("uid = ? and is_deleted = ?", userItem.UserGUID, constants.IsDeletedFalse).Find(&userPo).Error
		if err != nil && err != gorm.ErrRecordNotFound {
			return err
		}

		if userPo.Id == 0 {
			// 2. 保存账号
			userObj := user.GfyxUserPo{
				Uid:      userItem.UserGUID,
				Account:  userItem.UserCode,
				Name:     userItem.UserName,
				Mobile:   userItem.MobilePhone,
				Email:    userItem.Email,
				Position: userItem.Position,
				Salt:     userItem.Salt,
				Password: userItem.Password,
				LastSetPasswordTime: sql.NullTime{
					Valid: false,
				},
				Source:     3,
				Status:     status,
				CreatedOn:  time.Now(),
				CreatedBy:  "",
				ModifiedOn: time.Now(),
				ModifiedBy: "",
			}
			err = db.Save(userObj).Error
			if err != nil {
				return err
			}

			// 3. 用户与组织关系
			myuserbusinessunitmappingList := make([]*Myuserbusinessunitmapping, 0)
			err = db.Table(Myuserbusinessunitmapping{}.TableName()).
				Where("UserId = ?", userItem.UserGUID).Find(&myuserbusinessunitmappingList).Error
			if err != nil {
				return err
			}

			myuserbusinessunitIds := make([]string, 0)
			for _, userOrgRelObj := range myuserbusinessunitmappingList {
				myuserbusinessunitIds = append(myuserbusinessunitIds, userOrgRelObj.BUGUID)
			}

			orgList := make([]*org.GfyOrganizationPo, 0)
			err = db.Table(org.GfyOrganizationPo{}.TableName()).Where("Guid in (?)", myuserbusinessunitIds).Find(&orgList).Error
			if err != nil {
				return err
			}

			for _, orgItem := range orgList {
				userOrgRel := &user.GfyxUserOrganizationRelationPo{
					UserId:         userObj.Id,
					OrganizationId: orgItem.Id,
					//IsResponsible:  0,
					CreatedOn:  time.Now(),
					CreatedBy:  "",
					ModifiedOn: time.Now(),
					ModifiedBy: "",
				}
				err = db.Save(userOrgRel).Error
				if err != nil {
					return err
				}
			}
		}
	}

	return nil
}

// 处理myBusinessUnit内容同步
func (r *JmBaseRepository) saveOrg(ctx context.Context, db *gorm.DB) error {
	businessUnitList := make([]*MyBusinessUnit, 0)
	err := db.Find(&businessUnitList).Error
	if err != nil {
		return err
	}

	list := make([]*MyBusinessUnitItem, 0)
	for _, item := range businessUnitList {
		list = append(list, &MyBusinessUnitItem{
			BUCode:     item.BUCode,
			BUFullName: item.BUFullName,
			BUGUID:     item.BUGUID,
			BUName:     item.BUName,
			BUType:     item.BUType,
			ParentGUID: item.ParentGUID,
			Children:   nil,
		})
	}

	listTree := r.buildTrees(list)
	for _, item := range listTree {
		if item.ParentGUID == "" {
			r.saveJmToNewBase(ctx, db, 0, item)
		} else {
			stark.Logger.Infof(ctx, "buildTrees-info: %+v", item)
		}
	}

	return nil
}

func (r *JmBaseRepository) saveJmToNewBase(ctx context.Context, db *gorm.DB, parentId int64, obj *MyBusinessUnitItem) error {
	if obj != nil {
		// 1. 检查是否已存在
		var gop = &org.GfyOrganizationPo{}
		err := db.Table(org.GfyOrganizationPo{}.TableName()).Where("guid = ?", obj.BUGUID).First(gop).Error
		if err != nil && err != gorm.ErrRecordNotFound {
			return err
		}

		if gop == nil || gop.Id == 0 {
			orgItem := &org.GfyOrganizationPo{
				Guid:       obj.BUGUID,
				Name:       obj.BUName,
				FullName:   obj.BUFullName,
				ParentId:   parentId,
				ParentGuid: obj.ParentGUID,
				CreatedOn:  time.Now(),
				CreatedBy:  "",
				ModifiedOn: time.Now(),
				ModifiedBy: "",
			}

			err = db.Save(orgItem).Error
			if err != nil {
				return err
			}

			parentId = orgItem.Id
		} else {
			parentId = gop.Id
		}

		if obj.Children != nil {
			for _, c := range obj.Children {
				err = r.saveJmToNewBase(ctx, db, parentId, c)
				if err != nil {
					return err
				}
			}
		}
	}

	return nil
}
